<?php

namespace App\Console\Commands;

use App\Models\Agent;
use App\Models\Client;
use App\Models\Order;
use App\Services\Order\OrderContext;
use App\Services\Order\PlaceOrder;
use Carbon\Carbon;
use Illuminate\Console\Command;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Support\Facades\Redis;

class RestoreOrdersByCancelled extends Command
{
    /**
     * 命令名称及签名
     *
     * @var string
     */
    protected $signature = 'utils:restore_orders_by_canceled';

    /**
     * 命令描述
     *
     * @var string
     */
    protected $description = '被取消的订单重新下单';

    /**
     * 成功的订单 key
     * @var string
     */
    protected $successfulOrdersRedisHKey = 'RESTORE_ORDERS_BY_CANCELED:%s:SUCCESSFUL_ORDERS';

    /**
     * 失败的订单 key
     * @var string
     */
    protected $failedOrdersRedisHKey = 'RESTORE_ORDERS_BY_CANCELED:%s:FAILED_ORDERS';

    public function handle()
    {
        $batchNumber = $this->ask('请输入本次批次号', Carbon::now()->format('YmdHis'));
        empty($batchNumber) && $this->error('批次号不得为空');
        $cancelledOrders = explode(',', $this->ask('请输入要重新下单的订单号,多个订单号以逗号相隔'));
        empty($cancelledOrders) && $this->error('订单号不得为空');

        $bar = $this->output->createProgressBar(count($cancelledOrders));
        $bar->start();

        foreach ($cancelledOrders as $originOrderNumber) {
            try {
                try {
                    // 原来的订单
                    $originOrder = Order::query()->with('skus:id,order_id,amount,commodity_activity_sku_id')->where('numbering', $originOrderNumber)->firstOrFail();
                } catch (ModelNotFoundException $e) {
                    throw new \RuntimeException('订单号不存在');
                }

                try {
                    // 原来的客户
                    $client = Client::query()->with(['province', 'city', 'area'])->where(['id' => $originOrder['client_id'], 'agent_id' => $originOrder['agent_id']])->firstOrFail();
                } catch (ModelNotFoundException $e) {
                    throw new \RuntimeException('客户不存在');
                }

                // 原来的 sku id (同下单接口接收的数据结构一致)
                $skusList = [];
                foreach ($originOrder['skus'] as $sku) {
                    $skusList[$sku['commodity_activity_sku_id']] = [
                        'num' => $sku['amount'],
                        'sku_id' => $sku['commodity_activity_sku_id']
                    ];
                }

                $newOrder = (new OrderContext(
                    new PlaceOrder(
                        Agent::query()
                            ->with(['affiliatedPartner.partnerIdentity', 'directInviter', 'indirectInviter'])
                            ->findOrFail($originOrder['agent_id']),
                        $client,
                        $skusList,
                        '处理批次号(' . $batchNumber . ')恢复被取消的订单,原始订单号:' . $originOrderNumber
                    )))
                    ->excuteOperation([
                        'agent_id' => $originOrder['agent_id'],
                        'force_deduction_balance' => true
                    ])
                    ->getHandleResult();

                Redis::hset(sprintf($this->successfulOrdersRedisHKey, $batchNumber), $originOrderNumber, $newOrder['numbering']);
            } catch (\Throwable $e) {
                Redis::hset(sprintf($this->failedOrdersRedisHKey, $batchNumber), $originOrderNumber, $e->getMessage() . '(' . $e->getFile() . '[' . $e->getLine() . '])');
            } finally {
                $bar->advance();
            }
        }
        $bar->finish();
    }
}
